//==============================================================================
//
//               Copyright (C) 2004  Dick van Oudheusden
//  
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this program; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//==============================================================================
// 
//  $Date: 2005-01-01 07:47:56 $ $Revision: 1.2 $
//
//==============================================================================

#include <stdlib.h>

#include "ofc/config.h"

#include "ofc/DKey.h"
#include "ofc/DText.h"

#include "DInc.h"
#include "DTest.h"

//-Datatype--------------------------------------------------------------------

void DKey_test()
{
  DKey          *key1     = [DKey new];
  DKey          *key2     = [DKey alloc];
  DText         *text     = nil;
  char          *pntr     = NULL;
  char           wrong1[] = "f32";
  char           wrong2[] = "ctrl|a";
  char           empty[]  = "";
  
  STARTTEST();

  // Constructors
  TEST([key1 get] == 0);
  
  [key2 init :DKEY_MOD_ALT|DKEY_UP];
  
  TEST([key2 get ] == (DKEY_MOD_ALT|DKEY_UP));
  TEST([key2 key ] == DKEY_UP);
  TEST([key2 mod ] == DKEY_MOD_ALT);

  TEST(![key2 isCtrlKey]);
  TEST(![key2 isFunctionKey]);
  TEST( [key2 isAltKey]);
  TEST(![key2 isKeypadKey]);
  TEST(![key2 isShiftKey]);
  TEST(![key2 isMouseKey]);
  
  // Key setters
  [key2 set :DKEY_MOD_CTRL|DKEY_F1];
  
  TEST([key2 get ] == (DKEY_MOD_CTRL|DKEY_F1));
  TEST([key2 key ] == DKEY_F1);
  TEST([key2 mod ] == DKEY_MOD_CTRL);
  
  TEST( [key2 isCtrlKey]);
  TEST( [key2 isFunctionKey]);
  TEST(![key2 isAltKey]);
  TEST(![key2 isKeypadKey]);
  TEST(![key2 isShiftKey]);
  TEST(![key2 isMouseKey]);

  [key2 set :DKEY_F20];
  
  TEST([key2 get ] == DKEY_F20);
  TEST([key2 key ] == DKEY_F20);
  TEST([key2 mod ] == 0);

  TEST(![key2 isCtrlKey]);
  TEST( [key2 isFunctionKey]);
  TEST(![key2 isAltKey]);
  TEST(![key2 isKeypadKey]);
  TEST(![key2 isShiftKey]);
  TEST(![key2 isMouseKey]);
  
  [key2 set :DKEY_MOD_ALT|DKEY_MOD_CTRL|DKEY_DELETE];
  
  TEST([key2 get ] == (DKEY_MOD_ALT|DKEY_MOD_CTRL|DKEY_DELETE));
  TEST([key2 key ] == DKEY_DELETE);
  TEST([key2 mod ] == (DKEY_MOD_ALT|DKEY_MOD_CTRL));

  TEST( [key2 isCtrlKey]);
  TEST(![key2 isFunctionKey]);
  TEST( [key2 isAltKey]);
  TEST(![key2 isKeypadKey]);
  TEST(![key2 isShiftKey]);
  TEST(![key2 isMouseKey]);

  [key2 set :DKEY_MOD_SHIFT|DKEY_MOD_KP|DKEY_HOME];
  
  TEST([key2 get ] == (DKEY_MOD_SHIFT|DKEY_MOD_KP|DKEY_HOME));
  TEST([key2 key ] == DKEY_HOME);
  TEST([key2 mod ] == (DKEY_MOD_SHIFT|DKEY_MOD_KP));
  
  TEST(![key2 isCtrlKey]);
  TEST(![key2 isFunctionKey]);
  TEST(![key2 isAltKey]);
  TEST( [key2 isKeypadKey]);
  TEST( [key2 isShiftKey]);
  TEST(![key2 isMouseKey]);
  
  [key2 set :DKEY_ESCAPE];

  TEST([key2 get ] == DKEY_ESCAPE);
  TEST([key2 key ] == DKEY_ESCAPE);
  TEST([key2 mod ] == 0);
  
  TEST(![key2 isCtrlKey]);
  TEST(![key2 isFunctionKey]);
  TEST(![key2 isAltKey]);
  TEST(![key2 isKeypadKey]);
  TEST(![key2 isShiftKey]);
  TEST(![key2 isMouseKey]);

  // Mouse keys
  [key2 set :DKEY_MOD_CTRL|DKEY_MOUSE_LEFT];

  TEST([key2 get ] == (DKEY_MOD_CTRL|DKEY_MOUSE_LEFT));
  TEST([key2 key ] == DKEY_MOUSE_LEFT);
  TEST([key2 mod ] == DKEY_MOD_CTRL);

  TEST(([key2 get ] & DKEY_MOUSE_KEYS) != 0);
  TEST(([key2 key ] & DKEY_MOUSE_KEYS) != 0);

  TEST( [key2 isCtrlKey]);
  TEST(![key2 isFunctionKey]);
  TEST(![key2 isAltKey]);
  TEST(![key2 isKeypadKey]);
  TEST(![key2 isShiftKey]);
  TEST( [key2 isMouseKey]);

  [key2 set :DKEY_MOUSE_MIDDLE|DKEY_MOUSE_LEFT];

  TEST([key2 get ] == (DKEY_MOUSE_MIDDLE|DKEY_MOUSE_LEFT));
  TEST([key2 key ] == (DKEY_MOUSE_MIDDLE|DKEY_MOUSE_LEFT));
  TEST([key2 mod ] == 0);
  
  TEST(![key2 isCtrlKey]);
  TEST(![key2 isFunctionKey]);
  TEST(![key2 isAltKey]);
  TEST(![key2 isKeypadKey]);
  TEST(![key2 isShiftKey]);
  TEST( [key2 isMouseKey]);

  // Text convertor
  [key1 set :DKEY_MOD_CTRL|DKEY_ESCAPE];
  
  text = [key1 toText];
  TEST([text ccompare :"ctrl-escape"] == 0);
  [key1 set :DKEY_NULL];
  
  pntr = (char *) [text cstring]; // Don't do this at home..
  
  TEST([key1 fromString :&pntr] == 0);
  TEST([key1 get] == (DKEY_MOD_CTRL|DKEY_ESCAPE));
  TEST(*pntr == EOS);
  
  [text free];
  
  
  // Special 'ctrl' key: tab
  [key1 set :9];
  
  TEST(![key1 isCtrlKey]);
  
  text = [key1 toText];
  TEST([text ccompare :"ctrl-I"] == 0);
  
  [key1 set :'A'];
  
  pntr = (char *) [text cstring];
  
  TEST([key1 fromString :&pntr] == 0);
  TEST([key1 get] == 9);
  TEST(*pntr == EOS);
  
  TEST(![key1 isCtrlKey]);

  [text free];

  // Multiple modifiers
  [key1 set :DKEY_MOD_ALT|DKEY_MOD_CTRL|DKEY_DELETE];
  
  text = [key1 toText];
  TEST([text ccompare :"ctrl-alt-delete"] == 0);
  
  [key1 set :'A'];
  
  pntr = (char *) [text cstring];
  
  TEST([key1 fromString :&pntr] == 0);
  TEST([key1 get] == (DKEY_MOD_ALT|DKEY_MOD_CTRL|DKEY_DELETE));
  TEST(*pntr == EOS);
  
  [text free];

  // Function key
  [key1 set :DKEY_MOD_ALT|DKEY_F1];
  
  text = [key1 toText];
  TEST([text ccompare :"alt-f1"] == 0);
  
  [key1 set :'A'];
  
  pntr = (char *) [text cstring];
  
  TEST([key1 fromString :&pntr] == 0);
  TEST([key1 get] == (DKEY_MOD_ALT|DKEY_F1));
  TEST(*pntr == EOS);
  
  [text free];

  // Normal key
  [key1 set :'$'];
  
  text = [key1 toText];
  TEST([text ccompare :"$"] == 0);
  
  [key1 set :'A'];
  
  pntr = (char *) [text cstring];
  
  TEST([key1 fromString :&pntr] == 0);
  TEST([key1 get] == '$');
  TEST(*pntr == EOS);
  
  [text free];

  // Mouse key
  [key1 set :DKEY_MOD_ALT|DKEY_MOUSE_RIGHT|DKEY_MOUSE_LEFT];
  
  text = [key1 toText];
  TEST([text ccompare :"alt-mouse-right-left"] == 0);
  
  [key1 set :'A'];
  
  pntr = (char *) [text cstring];
  
  TEST([key1 fromString :&pntr] == 0);
  TEST([key1 get] == (DKEY_MOD_ALT|DKEY_MOUSE_RIGHT|DKEY_MOUSE_LEFT));
  TEST(*pntr == EOS);
  
  [text free];

  // Some wrong keys
  pntr = wrong1;

  TEST([key1 fromString :&pntr] == ERANGE);
  TEST(*pntr == 'f');
  
  pntr = wrong2;
  
  TEST([key1 fromString :&pntr] == 0); 
  TEST([key1 get] == DKEY_CTRL);  // ctrl|a = DKEY_CTRL ..
  TEST(*pntr == '|');
  
  pntr = empty;

  TEST([key1 fromString :&pntr] == ENODATA);
  
  [key2 free];
  [key1 free];
  
  STOPTEST();
}

